package com.gitee.wsl.func.filter.sample

import kotlin.math.abs


/**
 *
 * 可以移除元素的Bloom Filter数据结构实现
 *
 * @author Letcheng on 2016/2/24.
 */
class CountBloomFilter<E> : BloomFilter<E> {
    var count: IntArray
        protected set
    protected var c_m: Int = 0 // 当前使用的位数

    constructor(m: Int, n_max: Int, k: Int) : super(m, n_max, k) {
        this.count = IntArray(super.m)
    }

    constructor(fpp: Double, n_max: Int) : super(fpp, n_max) {
        this.count = IntArray(super.m)
    }

    public override fun add(bytes: ByteArray) {
        val hashes = createHashes(bytes, k)
        for (hash in hashes) {
            bitSet.set(abs(hash % m), true) //使用K个Hash函数映射到1位
            if (count[abs(hash % m)] == 0) {
                c_m++
            }
            count[abs(hash % m)] = count[abs(hash % m)] + 1
        }
        n++ //添加了一个元素
    }

    /**
     * 移除元素
     * @param element
     */
    fun remove(element: E) {
        if (element != null) {
            remove(element.toString().encodeToByteArray())
        }
    }

    /**
     * 移除字节数组
     * @param bytes
     */
    fun remove(bytes: ByteArray) {
        val hashes = createHashes(bytes, k)
        for (hash in hashes) {
            val dc = --count[abs(hash % m)]
            if (dc == 0) { //如果数据为空，则将标志位也归位
                c_m--
                bitSet.clear(abs(hash % m))
            }
        }
        n--
    }

    override fun clear() {
        this.count = IntArray(super.m)
        super.clear()
    }
}
